import * as qiniu from "qiniu-js";
import request from "@/utils/request";
import { ref } from "vue";

import type {
  UploadRequestOptions,
  UploadRawFile
} from "element-plus";

/**
 * 通过异步请求获取七牛云上传token
 * @returns 
 */
function getToken() {
  return request<any,IQiniuTokenResult>({url:"/qiniu/getToken"});
}

/**
 * 通过异步请求获取七牛云上传token（私有空间）
 * @returns 
 */
function getTokenSecret() {
  return request<any,IQiniuTokenResult>({url:"/qiniu/getTokenSecret"});
}

/**
 * 获取保存到七牛云的文件名，根据uuid生成文件名，key统一添加spf-的前缀方便管理
 * @param file 
 * @returns 
 */
const getKey = (file: UploadRawFile) => {
  const name = file.name;
  const arr = name.split(".")
  const suffix: string = arr.length >= 2 ? "." + arr[arr.length - 1] : "";
  // 七牛云上传参数
  const uid = file.uid ? file.uid : new Date().getTime();
  return `spf-${uid}${suffix}`;
}

/**
 * 获取上传的方法
 * @param secrect 是否上传到私有空间，私有空间有防盗链设置，视频等学习资源可以上传到私有空间
 * @returns 
 */
export default function getUpload(secrect?:boolean): IUploadResult {

  // 进度条的值
  const progressNum = ref(0);

  /**
   * 进行七牛云异步上传，返回Promise对象
   * @param options elementPlus的上传对象
   * @returns 
   */
  const asyncRequest = async (options: UploadRequestOptions): Promise<IUploadModel> => {
    let uploadOptions: IQiniuTokenResult;
    // file: http的formData对象
    const file = <UploadRawFile>options.file;

    try {
      let res;
      // 判断是获取私有库的token还是共有库的
      if (secrect) {
        res = await getTokenSecret()
      } else {
        res = await getToken();
      }
      uploadOptions = res.data.data;
    } catch {
      alert("获取token发生网络错误");
      return Promise.reject(null);
    }

    if (uploadOptions == null) {
      alert("获取上传token错误");
      return Promise.reject(null);
    }


    // 七牛云上传配置参数
    const config = {
      // 是否使用直传
      forceDirect: true,
      // 是否使用域名加速
      useCdnDomain: true,
      // 华南地区
      region: qiniu.region.z2,
    };
    // 七牛云上传配置参数（扩展参数）
    const putExtra = {
      fname: file.name, // 文件原文件名
      params: {}, // 放置自定义变量
      // mimeType: ["video/mp4", "video/ogg", "video/webm"], // 上传文件限制，null为不限制；限制类型放在数组中['image/png',"image/gif"]
      mineType: null,
    };

    // 上传开始，进度条归零
    progressNum.value = 0;

    // 获取保存的文件名
    const key = getKey(file);

    // 正式上传，返回一个监听对象
    const observable = qiniu.upload(file, key, uploadOptions.token, putExtra, config);
    return new Promise((resolve, reject) => {
      observable.subscribe({
        next(resProgress) {
          progressNum.value = Math.floor(resProgress.total.percent);
        }, // 查看上传进度条
        error() {
          alert("上传失败");
          reject(null);
        },
        // 上传成功
        complete(res) {
          alert("上传成功");

          // 1.5秒之后进度条值为0
          setTimeout(() => {
            progressNum.value = 0;
          }, 1500)

          // 成功后resolve结果
          resolve({
            file_path: `${uploadOptions.remoteAddr}/${res.key}`,
            file_name: file.name,
            content_length: file.size,
            content_type: file.type,
            key
          })
        },
      });
    })
  }
  return {asyncRequest, progressNum }
}